import numpy as np
import sympy
import math

# 定义预定值
x0 = np.array([[0], [0]])  # 初始值
E = 0.2 # 10 ** (-6)  # 到达精度就停止

# 定义函数及导数
f = lambda x: np.array(x[0] - x[1] + 2*(x[0]**2) + 2*x[0]*x[1] + x[1]**2) # 定义原函数
f_d = lambda x: np.array([ 1 + 4*x[0] + 2*x[1], -1 + 2*x[0] + 2*x[1]])  # 导数

n = 0 # 迭代次数
ee = f_d(x0) # 导数值
e=(ee[0]**2+ee[1]**2)**0.5 # 初始迭代精度
a=sympy.Symbol('a',real=True) # 最速下降法中的namita
# print ('第%d次迭代：e=%d' % (n, e))

# print("x0为：", x0)
# print("初始x0梯度为：", f_d(x0))
# print("\n")   

while e > E:       
    n = n + 1   
    yy = f(x0 - a * f_d(x0))  # f(x-ad)       
    yy_d = sympy.diff(yy[0], a)  # 以a为未知数，求导数
    a0 = sympy.solve(yy_d)  # a的值
    x0 = x0 - a0 * f_d(x0)  # 更新迭代 新的x
    ee = f_d(x0)  # 新的导数
    e = math.pow(math.pow(ee[0, 0], 2) + math.pow(ee[1, 0], 2), 0.5)
    
    print('第%d次迭代：e=%s' % (n, e))    
    print("f(x-ad)为：", yy)
    print("f(x-ad)以a为未知数，求导数为：", yy_d)
    print("得出a为：", a0)
    print("更新迭代 新的x1为：", x0)
    print("新的导数为：", ee)
    print("\n")   